package com.mango.iot.gateway.tcp.server;

import com.mango.iot.gateway.tcp.handler.codec.TransferDecoder;
import com.mango.iot.gateway.tcp.handler.TcpServerHandler;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.socket.SocketChannel;
import io.netty.handler.codec.DelimiterBasedFrameDecoder;
import io.netty.handler.timeout.IdleStateHandler;

import java.util.concurrent.TimeUnit;

/**
 * Sharable 注解 标注一个channel handler可以被多个channel安全地共享。
 * 为了安全地被用于多个并发的Channel（即连接），这样的ChannelHandler必须是线程安全的。
 *
 * @author liangfeihu
 * @number 53669
 * @since 2021/3/26 下午2:10
 */
@ChannelHandler.Sharable
public class ServerChannelInitializer extends ChannelInitializer<SocketChannel> {

    public static final int MAX_FRAME_LENGTH = 1024;
    public static final byte[] PACKET_START = new byte[]{0x78, 0x78};
    public static final byte[] PACKET_END = new byte[]{0x0D, 0x0A};

    @Override
    protected void initChannel(SocketChannel socketChannel) throws Exception {
        ChannelPipeline pipeline = socketChannel.pipeline();

        // 日志handler
        //pipeline.addLast(new LoggingHandler(LogLevel.INFO));

        // 空闲检测Handler
        pipeline.addLast(new IdleStateHandler(5 * 60, 0, 0, TimeUnit.SECONDS));

        // 固定分隔符第一解码器
        ByteBuf satrtDelimiter = Unpooled.copiedBuffer(PACKET_START);
        ByteBuf endDelimiter = Unpooled.copiedBuffer(PACKET_END);
        pipeline.addLast("delimiterBasedFrameDecoder", new DelimiterBasedFrameDecoder(MAX_FRAME_LENGTH, satrtDelimiter, endDelimiter));

        // 自定义第二解码器
        pipeline.addLast("transferDecoder", new TransferDecoder());

        // 不需要编码器，直接写二进制流出去
        //pipeline.addLast("transferEncoder", new TransferEncoder());

        // 业务处理handler
        pipeline.addLast("handler", new TcpServerHandler());
    }

}
